#include "Matrix.h"

Matrix * matrixnew(char* filename) {
    int i, j;
    FILE* f;
    f = fopen(filename, "r");
    if(!f) {
        printf("Error opening file: %s\n", filename);
        exit(EXIT_FAILURE);
    }

    Matrix * mymatrix = (Matrix *) calloc(sizeof(Matrix), 1);
    fscanf(f, "%d", &mymatrix->n);
    mymatrix->M = calloc(sizeof(float *), mymatrix->n);
    for(i=0; i < mymatrix->n; i++){
        mymatrix->M[i] = calloc(sizeof(float), mymatrix->n+1);
        for(j=0; j < mymatrix->n + 1; j++){
             fscanf(f, "%f", &mymatrix->M[i][j]);
        }
    }
    fclose(f);

    return mymatrix;
}

void matrixshow(Matrix * m){
    int i, j;
    if(!m) {
        printf("Null pointer at matrixshow()\n");
        exit(EXIT_FAILURE);
    }
    for(i=0; i < m->n; i++){
        for(j=0; j < m->n +1; j++){
            printf("%5.2f ", m->M[i][j]); // TODO blog this :-)
        }
        printf("\n");
    }
}

void matrixshowline(Matrix* m, int line){
    int j;
    if(!m) {
        printf("Null pointer at matrixget()\n");
        exit(EXIT_FAILURE);
    }
    if((line<0)||(line>m->n)){
        printf("Index out of bounds at matrixshowline(... , %d)\n", line);
        exit(EXIT_FAILURE);
    }
    for(j=0;j<m->n+1;j++){
        printf("%5.2f ", m->M[line][j]);
    }
    printf("\n");
}

float matrixget(Matrix* m, int line, int column) {
    if(!m) {
        printf("Null pointer at matrixget()\n");
        exit(EXIT_FAILURE);
    }
    if((line<0)||(line>m->n)||(column<0)||(column>m->n+1)){
        printf("Index out of bounds at matrixget(... , %d, %d)\n", line, column);
        exit(EXIT_FAILURE);
    }
    return m->M[line][column];
}

float * matrixgetline(Matrix* m, int line) {
    if(!m) {
        printf("Null pointer at matrixget()\n");
        exit(EXIT_FAILURE);
    }
    if((line<0)||(line>m->n)){
        printf("Index out of bounds at matrixget(... , %d)\n", line);
        exit(EXIT_FAILURE);
    }
    return m->M[line];
}

void matrixfree(Matrix * m) {
    int i, j;
    if(!m) {
        printf("Null pointer at matrixfree()\n");
        exit(EXIT_FAILURE);
    }
    for(i=0; i < m->n; i++){
        free(m->M[i]);
    }
    free(m->M);
    free(m);
}
